package com.qianfeng.openapi.web.master.controller;

import com.qianfeng.openapi.common.constant.OpenApiConstants;
import com.qianfeng.openapi.common.enums.OpenApiEnums;
import com.qianfeng.openapi.common.util.JSONUtil;
import com.qianfeng.openapi.web.master.bean.ResultVO;
import com.qianfeng.openapi.web.master.pojo.AdminUser;
import com.qianfeng.openapi.web.master.pojo.Menu;
import com.qianfeng.openapi.web.master.service.AdminUserService;
import com.qianfeng.openapi.web.master.service.MenuService;
import com.qianfeng.openapi.web.master.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static com.qianfeng.openapi.common.constant.OpenApiConstants.KEY;
import static com.qianfeng.openapi.common.constant.OpenApiConstants.REDIS_TIMEOUT;

/**
 * 登录功能,退出登录,侧边栏导航
 */
@RestController
@Slf4j
public class SystemController {


    @Autowired
    private AdminUserService adminUserService;

    @Autowired
    private MenuService menuService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 执行登录
     * 请求路径和请求方式：
     * <p>
     * - POST http://localhost:8080/dologin
     * <p>
     * 请求参数：
     * <p>
     * - [email](): String（必传项）
     * - [password](): String（必传项）
     */
    @PostMapping("/dologin")
    public ResultVO doLogin(String email, String password, HttpSession session, HttpServletResponse resp) {
        //1. 校验参数
        if (StringUtils.isEmpty(email) || StringUtils.isEmpty(password)) {
            log.info("【登录功能】 用户传递的参数不合法 email = {},password = {}", email, password);
            return R.error(OpenApiEnums.REQUEST_PARAMETER_ERROR.getStatus(), "用户名和密码均为必传项,岂能为空!");
        }

        //2. 调用Service执行登录,获取用户信息(让service抛异常)
        AdminUser adminUser = adminUserService.doLogin(email, password);

        /*//3. 将用户信息放到Session域
        session.setAttribute(OpenApiConstants.USER_SESSION,adminUser);*/
        //3. 将用户信息放到Redis中
        //3.1 准备key
        String keySuffix = UUID.randomUUID().toString().replace("-", "");
        String key = OpenApiConstants.USER_REDIS + keySuffix;

        //3.2 准备value
        String value = JSONUtil.toJSON(adminUser);

        //3.3 存放到Redis中
        redisTemplate.opsForValue().set(key,value,REDIS_TIMEOUT, TimeUnit.SECONDS);

        //4. 查询当前用户拥有的菜单信息
        List<Menu> menuList = menuService.findMenuListByUserId(adminUser.getId());

        /*//5. 将菜单信息保存到Session域中
        session.setAttribute(OpenApiConstants.USER_MENU,menuList);*/
        //5. 将菜单信息保存到Redis中
        //5.1 准备key
        String menuKey = OpenApiConstants.USER_MENU_REDIS + keySuffix;

        //5.2 准备value
        String menuValue = JSONUtil.toJSON(menuList);

        //5.3 存放到Redis
        redisTemplate.opsForValue().set(menuKey,menuValue,REDIS_TIMEOUT,TimeUnit.SECONDS);

        //6. 写回Cookie,让cookie中的值和Redis绑定
        Cookie cookie = new Cookie(KEY, keySuffix);
        cookie.setMaxAge(999999999);  //.....
        resp.addCookie(cookie);

        //7. 响应数据(登录成功)
        return R.ok(adminUser.getRealName());
    }


    /**
     * 退出登录
     * 请求路径和请求方式
     * <p>
     * - [POST]() http://localhost/logout
     * <p>
     * 请求参数
     * <p>
     * -   无
     */
    @PostMapping("/logout")  // TODO  @CookieValue
    public ResultVO logout(@CookieValue(value = KEY,required = false)String keySuffix) {
        //1. 删除
        redisTemplate.delete(OpenApiConstants.USER_REDIS + keySuffix);

        //2. 响应数据
        return R.ok();
    }

    /**
     * 侧边栏导航
     * 请求路径和请求方式
     * <p>
     * - [POST]()  http://localhost/side
     * <p>
     * 请求参数
     * <p>
     * -   无
     */
    @PostMapping("/side")   // TODO  @CookieValue
    public ResultVO side(@CookieValue(value = KEY)String keySuffix) {
//        0. 从Session域中获取用户信息
//        AdminUser adminUser = (AdminUser) session.getAttribute(OpenApiConstants.USER_SESSION);
//        Integer userId = adminUser.getId();
        //0. 从Redis获取数据
        String json = redisTemplate.opsForValue().get(OpenApiConstants.USER_REDIS + keySuffix);
        AdminUser adminUser = JSONUtil.fromJSON(json, AdminUser.class);
        if(adminUser == null){
            log.info("【侧边栏】 用户未登录！");
            return R.error(OpenApiEnums.NOT_LOGIN);
        }


        //1. 调用Service查询需要的导航信息
        List<Menu> data = menuService.findLeftSideNav(adminUser.getId());

        //2. 响应数据
        return R.ok(data);
    }


}
